package com.app.couponsharelife.data.remote.retrofit

import android.icu.text.Collator
import android.os.Build
import androidx.annotation.RequiresApi
import com.google.gson.*
import com.app.couponsharelife.manage.Contacts.REMOTE_URL
import com.app.couponsharelife.utils.AppUtils
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.lang.reflect.Type
import java.util.*
import java.util.concurrent.TimeUnit

/**
 *Created by Administrator on 2018/11/27
 *Description:
 */
class Network {
    private var appKey="&key=QzFFMEUwMEM2RDYyNTY4NzdCQkVGQTU1RkQxREI3"
    private var apiService:ApiService?=null
    private val okHttpClient = OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY))
            .connectTimeout(15, TimeUnit.SECONDS)
            .readTimeout(25, TimeUnit.SECONDS)
            .build()

    fun getFileRequest(url: String, file: File, maps: Map<String, String>?): Request {
        val builder = MultipartBody.Builder().setType(MultipartBody.FORM)
        if (maps == null) {
            builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"file\";filename=\"file.jpg\""), RequestBody.create(MediaType.parse("image/png"), file)
            ).build()

        } else {
            for (key in maps.keys) {
                builder.addFormDataPart(key, maps[key])
            }

            builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"file\";filename=\"file.jpg\""), RequestBody.create(MediaType.parse("image/png"), file)
            )
            val values = ArrayList<String>()
            for (key in maps.keys) {
                values.add(key.toUpperCase() + "=" + maps[key])
            }
            val param = StringBuilder()
            if (Build.VERSION.SDK_INT >= 23) {
                Collections.sort(values, Collator.getInstance(Locale.ENGLISH))
            } else {
                values.sort()
            }
            for (i in values.indices) {
                param.append(values[i])
            }

            val s = param.append("biaobingddki()&*HVFR$@TY$$%$%(&*^&ZXY12458i9u8jdedhgffr///||*&^GT\$RFWSA@").toString()
            //                        Log.e("eee",s);
            val sign = AppUtils.encryptMD5(s)
            builder.addFormDataPart("sign", sign)
        }
        val body = builder.build()
        return Request.Builder().url(url).post(body).build()

    }
    @RequiresApi(Build.VERSION_CODES.N)
    private val okHttpClientJK = OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .addInterceptor { chain ->
                var request = chain.request()
                if (request.body() is FormBody) {
                    val bodyBuilder = FormBody.Builder()
                    var formBody: FormBody = (request.body() as FormBody?)!!

                    val param = StringBuilder()

                    val values = ArrayList<String>()
                    val l = System.currentTimeMillis()
                    if (formBody.name(0) != "timestamp") {
                        values.add("timestamp=$l")
                    }
                    for (i in 0 until formBody.size()) {
                        if (formBody.value(i).isNotEmpty()) {
                            values.add(formBody.name(i) + "=" + formBody.value(i)+"&")
                            bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i))
                        }
                        //                            Log.e("eee",values.get(i));
                    }

                    if (Build.VERSION.SDK_INT >= 23) {
                        Collections.sort(values, Collator.getInstance(Locale.ENGLISH))
                    } else {
                        values.sort()
                    }
                    //                        Collections.sort(values);

                    for (i in values.indices) {
                        param.append(values[i])
                    }

                    val s = param.toString()+appKey
//
                    val sign = AppUtils.encryptMD5(s).toUpperCase()

                    if (formBody.name(0) != "timestamp") {
                        bodyBuilder.add("timestamp", l.toString())
                    }
                    bodyBuilder.add("sign", sign)
                    formBody = bodyBuilder.build()
                    request = request.newBuilder().post(formBody).build()
                }

                chain.proceed(request)
            }
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build()


    private val gsonConverterFactory = GsonConverterFactory.create(GsonBuilder()
            .setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
            .registerTypeAdapter(Boolean::class.java, BooleanSerializer())
            .registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanSerializer())
            .create())


    private val rxJavaCallAdapterFactory =RxJava2CallAdapterFactory.create()

    @RequiresApi(Build.VERSION_CODES.N)
    fun getApiService(): ApiService {
        if (apiService == null) {
            val retrofit = Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl(REMOTE_URL)
                    .addConverterFactory(gsonConverterFactory)
                    .addCallAdapterFactory(rxJavaCallAdapterFactory)
                    .build()
            apiService = retrofit.create(ApiService::class.java)
        }
        return apiService!!
    }


    internal class BooleanSerializer : JsonSerializer<Boolean>, JsonDeserializer<Boolean> {

        override fun serialize(arg0: Boolean?, arg1: Type, arg2: JsonSerializationContext): JsonElement {
            return JsonPrimitive(arg0!!)
        }

        @Throws(JsonParseException::class)
        override fun deserialize(arg0: JsonElement, arg1: Type, arg2: JsonDeserializationContext): Boolean? {
            val result: Boolean
            try {
                result = arg0.asInt == 1
            } catch (e: Exception) {
                return arg0.asBoolean
            }

            return result
        }
    }

    private val okHttpClientUUNum = OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .addInterceptor { chain ->
                var request = chain.request()
                if (request.body() is FormBody) {
                    val bodyBuilder = FormBody.Builder()
                    var formBody: FormBody = (request.body() as FormBody?)!!

                    val param = StringBuilder()

                    val values = ArrayList<String>()
                    val l = System.currentTimeMillis()
                    for (i in 0 until formBody.size() + 1) {
                        if (i == 0 || i == 1 || i == 2 || i == 3 || i == 4) {
                            values.add(i, formBody.name(i).toUpperCase() + "=" + formBody.value(i))
                            bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i))
                        } else if (i == 5) {
                            values.add(5, "TIMESTAMP=$l")
                        } else if (i == 6) {
                            values.add(6, formBody.name(5).toUpperCase() + "=" + formBody.value(5))
                            bodyBuilder.addEncoded(formBody.encodedName(5), formBody.encodedValue(5))
                        }
                    }

                    for (i in values.indices) {
                        param.append(values[i])
                    }

                    val s = param.append("biaobingddki()&*HVFR$@TY$$%$%(&*^&ZXY12458i9u8jdedhgffr///||*&^GT\$RFWSA@").toString()
                    //                        Log.e("eee",s);
                    val sign = AppUtils.encryptMD5(s)
                    //                        Log.e("eee1",sign);
                    //                        Log.e("eee3",formBody.size()+"");
                    bodyBuilder.add("TimesTamp", l.toString() + "")
                    bodyBuilder.add("sign", sign)
                    formBody = bodyBuilder.build()

                    request = request.newBuilder().post(formBody).build()
                }

                chain.proceed(request)
            }
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build()
}